home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
NeXTSTEP 3.3 (Developer)…68k, x86, SPARC, PA-RISC]
/
NeXTSTEP 3.3 Dev Intel.iso
/
NextDeveloper
/
Source
/
GNU
/
cctools
/
libstuff
/
arch.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-06-03
|
10KB
|
312 lines
#include "string.h"
#include <mach/mach.h>
#include "stuff/arch.h"
/*
* The array of all currently know architecture flags (terminated with an entry
* with all zeros). Pointer to this returned with get_arch_flags().
*/
static const struct arch_flag arch_flags[] = {
{ "any", CPU_TYPE_ANY, CPU_SUBTYPE_MULTIPLE },
{ "little", CPU_TYPE_ANY, CPU_SUBTYPE_LITTLE_ENDIAN },
{ "big", CPU_TYPE_ANY, CPU_SUBTYPE_BIG_ENDIAN },
/* architecture families */
{ "m68k", CPU_TYPE_MC680x0, CPU_SUBTYPE_MC680x0_ALL },
{ "m98k", CPU_TYPE_MC98000, CPU_SUBTYPE_MC98000_ALL },
{ "m88k", CPU_TYPE_MC88000, CPU_SUBTYPE_MC88000_ALL },
{ "i386", CPU_TYPE_I386, CPU_SUBTYPE_I386_ALL },
{ "i860", CPU_TYPE_I860, CPU_SUBTYPE_I860_ALL },
{ "hppa", CPU_TYPE_HPPA, CPU_SUBTYPE_HPPA_ALL },
{ "sparc", CPU_TYPE_SPARC, CPU_SUBTYPE_SPARC_ALL },
/* specific architecture implementations */
{ "m68030", CPU_TYPE_MC680x0, CPU_SUBTYPE_MC68030_ONLY },
{ "m68040", CPU_TYPE_MC680x0, CPU_SUBTYPE_MC68040 },
{ "i486", CPU_TYPE_I386, CPU_SUBTYPE_486 },
{ "i486SX", CPU_TYPE_I386, CPU_SUBTYPE_486SX },
{ "i586", CPU_TYPE_I386, CPU_SUBTYPE_586 },
{ "i586SX", CPU_TYPE_I386, CPU_SUBTYPE_586SX },
{ "hppa7100LC", CPU_TYPE_HPPA, CPU_SUBTYPE_HPPA_7100LC },
{ NULL, 0, 0 }
};
/*
* get_arch_from_flag() is passed a name of an architecture flag and returns
* zero if that flag is not known and non-zero if the flag is known.
* If the pointer to the arch_flag is not NULL it is filled in with the
* arch_flag struct that matches the name.
*/
int
get_arch_from_flag(
char *name,
struct arch_flag *arch_flag)
{
unsigned long i;
for(i = 0; arch_flags[i].name != NULL; i++){
if(strcmp(arch_flags[i].name, name) == 0){
if(arch_flag != NULL)
*arch_flag = arch_flags[i];
return(1);
}
}
if(arch_flag != NULL)
memset(arch_flag, '\0', sizeof(struct arch_flag));
return(0);
}
/*
* get_arch_from_host() gets the architecture from the host this is running on
* and returns zero if the architecture is not known and zero if the
* architecture is known. If the parameters family_arch_flag and
* specific_arch_flag are not NULL they get fill in with the family
* architecture and specific architecure for the host. If the architecture
* is unknown and the parameters are not NULL then all fields are set to zero.
*/
int
get_arch_from_host(
struct arch_flag *family_arch_flag,
struct arch_flag *specific_arch_flag)
{
struct host_basic_info host_basic_info;
unsigned int count;
kern_return_t r;
if(family_arch_flag != NULL)
memset(family_arch_flag, '\0', sizeof(struct arch_flag));
if(specific_arch_flag != NULL)
memset(specific_arch_flag, '\0', sizeof(struct arch_flag));
count = HOST_BASIC_INFO_COUNT;
if((r = host_info(host_self(), HOST_BASIC_INFO,
(host_info_t)(&host_basic_info),
&count)) != KERN_SUCCESS)
return(0);
if(family_arch_flag != NULL){
family_arch_flag->cputype = host_basic_info.cpu_type;
}
if(specific_arch_flag != NULL){
specific_arch_flag->cputype = host_basic_info.cpu_type;
specific_arch_flag->cpusubtype = host_basic_info.cpu_subtype;
}
switch(host_basic_info.cpu_type){
case CPU_TYPE_MC680x0:
switch(host_basic_info.cpu_subtype){
case CPU_SUBTYPE_MC680x0_ALL:
case CPU_SUBTYPE_MC68030_ONLY:
if(family_arch_flag != NULL){
family_arch_flag->name = "m68k";
family_arch_flag->cpusubtype = CPU_SUBTYPE_MC680x0_ALL;
}
if(specific_arch_flag != NULL){
specific_arch_flag->name = "m68030";
/*
* There is a "bug" in the kernel for compatiblity that on
* an 030 machine host_info() returns cpusubtype
* CPU_SUBTYPE_MC680x0_ALL and not CPU_SUBTYPE_MC68030_ONLY.
*/
specific_arch_flag->cpusubtype = CPU_SUBTYPE_MC68030_ONLY;
}
return(1);
case CPU_SUBTYPE_MC68040:
if(family_arch_flag != NULL){
family_arch_flag->name = "m68k";
family_arch_flag->cpusubtype = CPU_SUBTYPE_MC680x0_ALL;
}
if(specific_arch_flag != NULL)
specific_arch_flag->name = "m68040";
return(1);
}
break;
case CPU_TYPE_MC98000:
switch(host_basic_info.cpu_subtype){
case CPU_SUBTYPE_MC98000_ALL:
if(family_arch_flag != NULL){
family_arch_flag->name = "m98k";
family_arch_flag->cpusubtype = CPU_SUBTYPE_MC98000_ALL;
}
if(specific_arch_flag != NULL)
specific_arch_flag->name = "m98k";
return(1);
}
break;
case CPU_TYPE_MC88000:
switch(host_basic_info.cpu_subtype){
case CPU_SUBTYPE_MC88000_ALL:
case CPU_SUBTYPE_MC88110:
if(family_arch_flag != NULL){
family_arch_flag->name = "m88k";
family_arch_flag->cpusubtype = CPU_SUBTYPE_MC88000_ALL;
}
if(specific_arch_flag != NULL)
specific_arch_flag->name = "m88k";
return(1);
}
break;
case CPU_TYPE_I386:
switch(host_basic_info.cpu_subtype){
case CPU_SUBTYPE_I386_ALL:
/* case CPU_SUBTYPE_386: same value as above */
if(family_arch_flag != NULL){
family_arch_flag->name = "i386";
family_arch_flag->cpusubtype = CPU_SUBTYPE_I386_ALL;
}
if(specific_arch_flag != NULL)
specific_arch_flag->name = "i386";
return(1);
case CPU_SUBTYPE_486:
if(family_arch_flag != NULL){
family_arch_flag->name = "i386";
family_arch_flag->cpusubtype = CPU_SUBTYPE_I386_ALL;
}
if(specific_arch_flag != NULL)
specific_arch_flag->name = "i486";
return(1);
case CPU_SUBTYPE_486SX:
if(family_arch_flag != NULL){
family_arch_flag->name = "i386";
family_arch_flag->cpusubtype = CPU_SUBTYPE_I386_ALL;
}
if(specific_arch_flag != NULL)
specific_arch_flag->name = "i486SX";
return(1);
case CPU_SUBTYPE_586:
if(family_arch_flag != NULL){
family_arch_flag->name = "i386";
family_arch_flag->cpusubtype = CPU_SUBTYPE_I386_ALL;
}
if(specific_arch_flag != NULL)
specific_arch_flag->name = "i586";
return(1);
case CPU_SUBTYPE_586SX:
if(family_arch_flag != NULL){
family_arch_flag->name = "i386";
family_arch_flag->cpusubtype = CPU_SUBTYPE_I386_ALL;
}
if(specific_arch_flag != NULL)
specific_arch_flag->name = "i586SX";
return(1);
}
break;
case CPU_TYPE_I860:
switch(host_basic_info.cpu_subtype){
case CPU_SUBTYPE_I860_ALL:
case CPU_SUBTYPE_I860_860:
if(family_arch_flag != NULL){
family_arch_flag->name = "i860";
family_arch_flag->cpusubtype = CPU_SUBTYPE_I860_ALL;
}
if(specific_arch_flag != NULL)
specific_arch_flag->name = "i860";
return(1);
}
break;
case CPU_TYPE_HPPA:
switch(host_basic_info.cpu_subtype){
case CPU_SUBTYPE_HPPA_ALL:
if(family_arch_flag != NULL){
family_arch_flag->name = "hppa";
family_arch_flag->cpusubtype = CPU_SUBTYPE_HPPA_ALL;
}
if(specific_arch_flag != NULL)
specific_arch_flag->name = "hppa";
return(1);
case CPU_SUBTYPE_HPPA_7100LC:
if(family_arch_flag != NULL){
family_arch_flag->name = "hppa";
family_arch_flag->cpusubtype = CPU_SUBTYPE_HPPA_ALL;
}
if(specific_arch_flag != NULL)
specific_arch_flag->name = "hppa7100LC";
return(1);
}
break;
case CPU_TYPE_SPARC:
switch(host_basic_info.cpu_subtype){
case /*CPU_SUBTYPE_SPARC_ALL*/0:
if(family_arch_flag != NULL){
family_arch_flag->name = "sparc";
family_arch_flag->cpusubtype = CPU_SUBTYPE_SPARC_ALL;
}
if(specific_arch_flag != NULL)
specific_arch_flag->name = "sparc";
return(1);
}
break;
}
return(0);
}
/*
* get_arch_flags() returns a pointer to an array of all currently know
* architecture flags (terminated with an entry with all zeros).
*/
const struct arch_flag *
get_arch_flags(
void)
{
return(arch_flags);
}
/*
* get_arch_name_from_types() returns the name of the architecture for the
* specified cputype and cpusubtype if known. If unknown it returns a pointer
* to the string "unknown".
*/
const char *
get_arch_name_from_types(
cpu_type_t cputype,
cpu_subtype_t cpusubtype)
{
unsigned long i;
for(i = 0; arch_flags[i].name != NULL; i++){
if(arch_flags[i].cputype == cputype &&
arch_flags[i].cpusubtype == cpusubtype)
return(arch_flags[i].name);
}
return("unknown");
}
/*
* get_arch_family_from_cputype() returns the family architecture for the
* specified cputype if known. If unknown it returns NULL.
*/
const struct arch_flag *
get_arch_family_from_cputype(
cpu_type_t cputype)
{
unsigned long i;
for(i = 0; arch_flags[i].name != NULL; i++){
if(arch_flags[i].cputype == cputype)
return(arch_flags + i);
}
return(NULL);
}
/*
* get_byte_sex_from_flag() returns the byte sex of the architecture for the
* specified cputype and cpusubtype if known. If unknown it returns
* UNKNOWN_BYTE_SEX. If the bytesex can be determined directly as in the case
* of reading a magic number from a file that should be done and this routine
* should not be used as it could be out of date.
*/
enum byte_sex
get_byte_sex_from_flag(
const struct arch_flag *flag)
{
if(flag->cputype == CPU_TYPE_MC680x0 ||
flag->cputype == CPU_TYPE_MC88000 ||
flag->cputype == CPU_TYPE_MC98000 ||
flag->cputype == CPU_TYPE_HPPA ||
flag->cputype == CPU_TYPE_SPARC ||
flag->cputype == CPU_TYPE_I860)
return BIG_ENDIAN_BYTE_SEX;
else if(flag->cputype == CPU_TYPE_I386)
return LITTLE_ENDIAN_BYTE_SEX;
else
return UNKNOWN_BYTE_SEX;
}